const { default: BigNumber } = require('bignumber.js');
const { times } = require('lodash');
const moment = require('moment/moment.js');
const { think } = require('thinkjs');

module.exports = class extends think.Model {
  async jiafang() {
    const projectList = await this.model('project_list')
      .where({ type: 1 })
      .select();
    for (const projectItem of projectList) {
      const has = await this.model('contract_list')
        .where({ project_id: projectItem.id, type: 2, status: 1 })
        .select();

      if (think.isEmpty(has)) {
        continue;
      }

      //房源成本
      for (const item of has) {
        const months = moment(item.date_end)
          .add(1, 'days')
          .diff(moment(item.date_start), 'month');

        let ny = 0;

        if (item.nengyuan) {
          ny = BigNumber(item.nengyuan)
            .times(BigNumber(months))
            .times(BigNumber(item.area_contract))
            .toFixed(2);
        }

        const chengben = BigNumber(item.fangzu)
          .plus(BigNumber(item.wuye))
          .plus(BigNumber(ny))
          .div(BigNumber(item.area))
          .div(months || 1);

        const restMoney = BigNumber(item.fangzu)
          .plus(BigNumber(item.wuye))
          .plus(BigNumber(ny))
          .div(BigNumber(item.area));

        const infos = JSON.parse(item.project);

        for (const itemInfo of infos) {
          if (itemInfo.length === 3) {
            const rooms = await this.model('project_list')
              .where({
                floor_id: itemInfo[2],
                type: 5,
              })
              .select();
            for (const itemRoom of rooms) {
              const cost = BigNumber(chengben).times(BigNumber(itemRoom.area));
              const roomRest = restMoney.times(BigNumber(itemRoom.area));
              await this.model('project_list')
                .where({ id: itemRoom.id })
                .update({
                  chengben: cost.toFixed(2),
                  rest: roomRest.toFixed(2),
                  chengben_unit: BigNumber(item.fangzu_unit)
                    .plus(BigNumber(item.wuye_unit))
                    .plus(BigNumber(item.nengyuan || 0))
                    .toFixed(2),
                });
            }
          }
        }
      }
    }
    await this.tax();
    await this.manage();
    await this.ticheng();
    await this.zhuangxiu();
    await this.zhaoshang();
    await this.shouru();
    await this.yue();
    await this.contractLog();
  }

  async ticheng() {}
  async manage() {}
  async zhaoshang() {
    const expendList = await this.model('expend_list')
      .where({ expend_type: 'bussiness' })
      .select();
    for (const expendItem of expendList) {
      if (expendItem.project) {
        const arrRooms = JSON.parse(expendItem.project);
        const rooms = [];
        for (const roomItem of arrRooms) {
          rooms.push(roomItem[3]);
        }
        const money =
          (await this.model('output_list')
            .where({ type: 'bussiness', expend_id: expendItem.id, status: 1 })
            .sum('money')) || 0;

        const area = await this.model('project_list')
          .where({ type: 4, id: ['IN', rooms] })
          .sum('area');

        const fee = BigNumber(money).div(BigNumber(area));

        const roomList = await this.model('project_list')
          .where({ type: 4, id: ['IN', rooms] })
          .select();

        for (const itemRoom of roomList) {
          if (!itemRoom.origin_id) {
            continue;
          }

          const floor = await this.model('project_list')
            .where({ type: 3, id: itemRoom.floor_id })
            .find();

          const months = moment(floor.contract_time_end)
            .add(1, 'days')
            .diff(moment(floor.contract_time), 'month');

          const originRoom = await this.model('project_list')
            .where({ type: 5, id: itemRoom.origin_id })
            .find();

          const m = BigNumber(originRoom.chengben)
            .plus(fee.times(itemRoom.area).div(months))
            .toFixed(2);

          await this.model('project_list')
            .where({ id: itemRoom.origin_id })
            .update({
              chengben: m,
              chengben_unit: BigNumber(originRoom.chengben_unit)
                .plus(fee.div(BigNumber(months)))
                .toFixed(2),
            });
        }
      }
    }
  }

  async tax() {
    const projectList = await this.model('project_list')
      .where({ type: 1 })
      .select();
    for (const projectItem of projectList) {
      //税务成本
      const taxTotal = await this.model('bill_list')
        .where({ project_id: projectItem.id })
        .sum('tax');

      const areas = await this.model('project_list')
        .where({ type: 4, project_id: projectItem.id })
        .sum('area');

      const perTax = BigNumber(taxTotal).div(BigNumber(areas));

      const rooms = await this.model('project_list')
        .where({ type: 4, project_id: projectItem.id })
        .select();

      for (const item of rooms) {
        if (!item.origin_id) {
          continue;
        }

        const originRoom = await this.model('project_list')
          .where({ type: 5, id: item.origin_id })
          .find();

        const floor = await this.model('project_list')
          .where({ type: 3, id: item.floor_id })
          .find();

        const months = moment(floor.contract_time_end)
          .add(1, 'days')
          .diff(moment(floor.contract_time), 'month');

        const m = BigNumber(originRoom.chengben)
          .plus(perTax.times(item.area).div(months))
          .toFixed(2);

        if (item.origin_id) {
          await this.model('project_list')
            .where({ id: item.origin_id })
            .update({
              chengben: m,
              chengben_unit: BigNumber(originRoom.chengben_unit)
                .plus(perTax.div(BigNumber(months)))
                .toFixed(2),
            });
        }
      }
    }
  }

  async shouru() {
    await this.model('project_list')
      .where({ type: ['IN', [4, 5]] })
      .update({
        status: 1,
        lirun: 0,
        zujin: 0,
        shouru_unit: 0,
        lirun_unit: 0,
      });

    const projectList = await this.model('project_list')
      .where({ type: 1 })
      .select();

    for (const projectItem of projectList) {
      const has = await this.model('contract_list')
        .where({ project_id: projectItem.id, type: 1 })
        .order(['status DESC'])
        .select();
      //租赁合同列表

      if (think.isEmpty(has)) {
        continue;
      }

      for (const item of has) {
        const arr = JSON.parse(item.project);

        const room = [];
        for (const itemRoom of arr) {
          if (itemRoom[3]) {
            room.push(itemRoom[3]);
          }
        }

        const months = moment(item.date_end)
          .add(1, 'days')
          .diff(moment(item.date_start), 'month');

        if (!item.area_contract) {
          continue;
        }

        if (!months) {
          continue;
        }

        const zujin = BigNumber(item.fangzu)
          .plus(BigNumber(item.wuye))
          .div(BigNumber(item.area_contract))
          .div(months);

        const roomsData = await this.model('project_list')
          .where({
            id: ['IN', room],
          })
          .select();

        for (const itemRoom of roomsData) {
          const cost = BigNumber(zujin)
            .times(BigNumber(itemRoom.area))
            .plus(itemRoom.zujin);

          const origin = await this.model('project_list')
            .where({ id: itemRoom.origin_id })
            .find();

          const chengben = BigNumber(origin.chengben_unit).times(
            BigNumber(itemRoom.area)
          );

          const lirun = cost.minus(BigNumber(chengben)).plus(itemRoom.lirun);

          //甲方合同期限获取
          const floor = await this.model('project_list')
            .where({ type: 3, id: itemRoom.floor_id })
            .find();

          // const monthsJiafang = moment(floor.contract_time_end)
          //   .add(1, 'days')
          //   .diff(moment(floor.contract_time), 'month');

          if (itemRoom.origin_id) {
            const originZujin = BigNumber(origin.zujin).plus(cost);
            const originLirun = BigNumber(origin.lirun).plus(lirun);
            await this.model('project_list')
              .where({ id: itemRoom.origin_id })
              .update({
                lirun: originLirun.toFixed(2),
                zujin: originZujin.toFixed(2),
                // shouru_unit: BigNumber(item.fangzu_unit)
                //   .plus(BigNumber(item.wuye_unit))
                //   .toFixed(2),
                // lirun_unit: BigNumber(item.fangzu_unit)
                //   .plus(BigNumber(item.wuye_unit))
                //   .minus(BigNumber(itemRoom.chengben_unit))
                //   .toFixed(2),
              });
          }

          if (item.status !== 3) {
            await this.model('project_list')
              .where({ id: itemRoom.id })
              .update({
                lirun: lirun.toFixed(2),
                zujin: cost.toFixed(2),
                shouru_unit: BigNumber(item.fangzu_unit)
                  .plus(BigNumber(item.wuye_unit))
                  .toFixed(2),
                lirun_unit: BigNumber(item.fangzu_unit)
                  .plus(BigNumber(item.wuye_unit))
                  .minus(BigNumber(itemRoom.chengben_unit))
                  .toFixed(2),
                status: 2,
              });

            await this.model('project_log')
              .where({ contract_id: item.id, room_id: itemRoom.id })
              .delete();

            await this.model('project_log').add({
              project_id: itemRoom.project_id,
              floor_id: itemRoom.floor_id,
              room_id: itemRoom.id,
              area: item.area_contract,
              contract_id: item.id,
              jiafang_start: floor.contract_time,
              jiafang_end: floor.contract_time_end,
              contract_start: item.date_start,
              contract_end: item.date_end,
              rent_start: item.date_start,
              rent_end: item.date_end,
              status: 1,
              lirun: lirun.toFixed(2),
              zujin: cost.toFixed(2),
              zujin_total: BigNumber(zujin)
                .times(BigNumber(itemRoom.area))
                .times(BigNumber(months))
                .toFixed(2),
              chengben: itemRoom.chengben,
              chengben_total: BigNumber(itemRoom.chengben_unit)
                .times(BigNumber(months))
                .times(BigNumber(itemRoom.area))
                .toFixed(2),
            });
          } else {
            const shouru = await this.model('income_list')
              .where({
                contract_id: item.id,
                status: 1,
                type: ['IN', ['fangzu', 'wuye', 'ruzhang', 'bujiao']],
              })
              .sum('money');

            const hasEndContract = await this.model('project_log')
              .where({ contract_id: item.id })
              .find();

            if (think.isEmpty(hasEndContract)) {
              await this.model('project_log').add({
                project_id: itemRoom.project_id,
                floor_id: itemRoom.floor_id,
                room_id: itemRoom.id,
                area: item.area_contract,
                contract_id: item.id,
                jiafang_start: floor.contract_time,
                jiafang_end: floor.contract_time_end,
                contract_start: item.date_start,
                contract_end: item.date_end,
                rent_start: item.date_start,
                rent_end: item.tuizuDate,
                status: 2,
                lirun: lirun.toFixed(2),
                zujin: cost.toFixed(2),
                zujin_total: shouru || 0,
                chengben: itemRoom.chengben,
                chengben_total: BigNumber(itemRoom.chengben_unit)
                  .times(BigNumber(months))
                  .times(BigNumber(itemRoom.area))
                  .toFixed(2),
              });
            } else {
              await this.model('project_log')
                .where({ contract_id: item.id })
                .update({
                  status: 2,
                  rent_end: item.tuizuDate,
                  zujin_total: shouru || 0,
                  // jiafang_start: floor.contract_time,
                  // jiafang_end: floor.contract_time_end,
                  // chengben_total: BigNumber(itemRoom.chengben_unit)
                  //   .times(BigNumber(months))
                  //   .times(BigNumber(itemRoom.area))
                  //   .toFixed(2),
                });
            }
          }
        }
      }
    }
  }

  async yue() {
    const projectList = await this.model('project_list')
      .where({ type: 1 })
      .select();
    for (const projectItem of projectList) {
      const has = await this.model('contract_list')
        .where({ project_id: projectItem.id, type: 1 })
        .select();

      for (const item of has) {
        const arr = JSON.parse(item.project);
        const room = [];
        for (const itemRoom of arr) {
          if (itemRoom[3]) {
            room.push(itemRoom[3]);
          }
        }

        if (!item.area_contract) {
          continue;
        }

        const zujin = BigNumber(item.fangzu)
          .plus(BigNumber(item.wuye))
          .div(BigNumber(item.area_contract));

        const roomsData = await this.model('project_list')
          .where({
            id: ['IN', room],
          })
          .select();

        for (const itemRoom of roomsData) {
          const roomRest = await this.model('project_list')
            .where({ id: itemRoom.origin_id })
            .getField('rest', true);
          if (roomRest) {
            const cost = BigNumber(zujin).times(BigNumber(itemRoom.area));
            const rest = BigNumber(roomRest)
              .minus(BigNumber(cost))
              .toFixed(0);
            if (itemRoom.origin_id) {
              this.model('project_list')
                .where({ id: itemRoom.origin_id })
                .update({
                  rest: rest,
                });
            }
          }
        }
      }
    }
  }

  async zhuangxiu() {
    const expendList = await this.model('expend_list')
      .where({ expend_type: 'base' })
      .select();
    for (const expendItem of expendList) {
      if (expendItem.project) {
        const arrRooms = JSON.parse(expendItem.project);
        const rooms = [];
        for (const roomItem of arrRooms) {
          rooms.push(roomItem[3]);
        }
        const money =
          (await this.model('output_list')
            .where({ type: 'base', expend_id: expendItem.id, status: 1 })
            .sum('money')) || 0;

        const area = await this.model('project_list')
          .where({ type: 4, id: ['IN', rooms] })
          .sum('area');

        const fee = BigNumber(money).div(BigNumber(area));

        const roomList = await this.model('project_list')
          .where({ type: 4, id: ['IN', rooms] })
          .select();

        for (const itemRoom of roomList) {
          const floor = await this.model('project_list')
            .where({ type: 3, id: itemRoom.floor_id })
            .find();

          const months = moment(floor.contract_time_end)
            .add(1, 'days')
            .diff(moment(floor.contract_time), 'month');

          const m = BigNumber(itemRoom.chengben)
            .plus(fee.times(itemRoom.area).div(months))
            .toFixed(2);

          if (itemRoom.origin_id) {
            await this.model('project_list')
              .where({ id: itemRoom.origin_id })
              .update({
                chengben: m,
                chengben_unit: BigNumber(itemRoom.chengben_unit)
                  .plus(fee.div(BigNumber(months)))
                  .toFixed(2),
              });
          }
        }
      }
    }
  }
  async projectLog() {}
  async contractLog() {
    const inComeList = await this.model('income_list')
      .where({ contract_id: ['!=', null], project_id: null })
      .select();
    for (const item of inComeList) {
      const contract = await this.model('contract_list')
        .where({ id: item.contract_id })
        .find();
      if (!think.isEmpty(contract)) {
        if (contract.project_id) {
          await this.model('income_list')
            .where({ id: item.id })
            .update({
              project_id: contract.project_id,
            });
        }
      }
    }

    ////

    await this.model('contract_line')
      .where({ id: ['>', 0] })
      .delete();

    //

    const start = moment();
    const end = moment().add(3, 'years');

    const project = await this.model('project_list')
      .where({ type: 1 })
      .field('name, id')
      .select();

    const num = end.diff(start, 'months');

    for (const item of project) {
      item.startData = moment();
    }

    for (let i = 0; i < project.length; i++) {
      for (let j = 0; j < num; j++) {
        const searchDate = project[i].startData
          .add(1, 'months')
          .endOf('month')
          .format('YYYY-MM-DD');

        const jiafangFangzu = await this.model('contract_list')
          .where({
            type: 2,
            project_id: project[i].id,
            date_end: ['>=', searchDate],
            date_start: ['<=', searchDate],
          })
          .sum('fangzu');
        const jiafangWuye = await this.model('contract_list')
          .where({
            type: 2,
            project_id: project[i].id,
            date_end: ['>=', searchDate],
            date_start: ['<=', searchDate],
          })
          .sum('wuye');

        let jiafangTotal = BigNumber(jiafangFangzu || 0).plus(
          BigNumber(jiafangWuye || 0)
        );

        // const rest = await this.model('project_log')
        //   .where({
        //     project_id: project[i].id,
        //     rent_end: ['<=', moment().format('YYYY-MM-DD')],
        //   })
        //   .sum('zujin_total');

        // jiafangTotal = jiafangTotal.minus(BigNumber(rest || 0));

        let sum = BigNumber(0);

        const hetong = await this.model('contract_list')
          .where({
            type: 1,
            project_id: project[i].id,
            date_start: ['<=', searchDate],
            date_end: ['>', searchDate],
          })
          .select();

        for (const itemHetong of hetong) {
          if (itemHetong.fangzu_unit && itemHetong.wuye_unit) {
            const fee = BigNumber(itemHetong.fangzu_unit)
              .times(itemHetong.area_contract)
              .plus(
                BigNumber(itemHetong.wuye_unit).times(itemHetong.area_contract)
              );

            sum = sum.plus(fee);
          }
        }

        const prev = await this.model('contract_line')
          .where({
            project_id: project[i].id,
          })
          .order(['id DESC'])
          .find();

        let total;
        if (think.isEmpty(prev)) {
          total = sum.minus(jiafangTotal).toFixed();
        } else {
          total = sum.plus(prev.total).toFixed();
        }

        await this.model('contract_line').add({
          project_id: project[i].id,
          month: moment(searchDate).format('YYYY-MM'),
          total: total,
          prev: prev.total,
          shouru: sum.toFixed(2),
        });
      }
    }
  }
};
